using System.Collections.Generic;
using BitBenderGames;
using DG.Tweening;
using GameFramework.Battle.Core;
using Gameplay.PVE.Entity;
using Gameplay.PVE.UI;
using Gameplay.PVE.Utils;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.UI;
using WorldMap.CameraController;
using Yoozoo.Framework.Managers;
using Yoozoo.Gameplay.Core;
using Yoozoo.Gta.Common;
using Yoozoo.Managers;
using Yoozoo.UI.YGUI;

namespace Gameplay.PVE
{
    public class OperationManager
    {
        private BattleUnit lastTouchUnit;
        private BattleUnit lastDragTarget;
        private uint dragLineId = 0;
        public static bool enable = true;
        private Vector4 mapBoundary;
        private int state = 0;//0 普通 1 正在技能选敌 2 正在放障碍物
        private BattleUnit skillUnit;

        private static OperationManager instance;
        private PveTouchController touchController;

        private GameObject canvas;
        private GameObject touchKnob;
        private RectTransform touchKnobTrans;
        private Image touchKnobImage;
        private RectTransform canvasTrans;

        private GameObject joyStick;
        private GameObject pveOperator;

        private RectTransform canvasParentTrans;

        private PveJoyStick joy;
        
        private int skillTouchFingerId;
        
        private Vector3 touchPosition;

        public bool isRpgControlling;

        public static OperationManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new OperationManager();
                }
                return instance;
            }
            
        }
        
        
        private BattleUnit currentSelectUnit;
        public void Initialize()
        {
            //enable = false;
            
            touchController = new PveTouchController();
            touchController.OnDragStart += OnDragStart;
            touchController.OnDragEnd += OnDragEnd;
            touchController.OnDrag += OnDrag;
            touchController.OnTouchStart += OnTouchStart;
            touchController.OnTouchEnd += OnTouchUp;
            
            lastTouchUnit = null;
            
            var canvasParent = GameObject.Find("UIRoot/RootCanvas");
            canvas = new GameObject("PveTouchingKnobCanvas");
            canvas.SetLayerRecursively(LayerMask.NameToLayer("UI"));
            canvas.transform.SetParent(canvasParent.transform);
            var canvasCom = canvas.AddComponent<Canvas>();
            canvasCom.overrideSorting = true;
            canvasCom.sortingOrder = 100;
            canvas.AddComponent<GraphicRaycaster>();
            canvasTrans = canvas.GetComponent<RectTransform>();
            canvasParentTrans = canvasParent.gameObject.GetComponent<RectTransform>();
            canvasTrans.sizeDelta = canvasParentTrans.sizeDelta;

#if UNITY_EDITOR
            touchKnob = PveResourceManager.GetResource(PveResourceManager.EPveResType.UI, 11);
            touchKnob.transform.SetParent(canvas.transform);
            touchKnob.SetActive(true);
            touchKnobTrans = touchKnob.GetComponent<RectTransform>();
            touchKnobImage = touchKnob.GetComponent<Image>();
#endif
            if (PveManager.Instance.isManualMoving)
            {
                joyStick = PveResourceManager.GetResource(PveResourceManager.EPveResType.UI, 12);
                joyStick.SetActive(true);
                joyStick.transform.SetParent(canvas.transform);
                joyStick.GetComponent<RectTransform>().anchoredPosition = new Vector2(0,0);
                joy = joyStick.GetComponent<PveJoyStick>();
                joy.Init();
                joy.SetOnDrag(UnitMove);
                
                /*pveOperator = PveResourceManager.GetResource(PveResourceManager.EPveResType.UI, 15);
                pveOperator.SetActive(true);
                pveOperator.transform.SetParent(canvas.transform);
                pveOperator.GetComponent<RectTransform>().anchoredPosition = new Vector2((canvasParentTrans.sizeDelta.x / 2 - 200),-150);
                
                var joy2 = pveOperator.GetComponent<PveJoyStick>();
                joy2.Init();
                joy2.SetOnDrag(UnitAim);
                joy2.SetOnPress(UnitAttack,0.5f);*/
                /*var btn = pveOperator.GetComponentInChildren<YButton>();
                btn.onClick.AddListener(() =>
                {
                    if (controllingUnit == null)
                    {
                        controllingUnit = UnitManager.Instance.GetUnit(0);
                    }
                    controllingUnit.Transmit(ETransmitType.Attack);
                    controllingUnit.Data.needNextShoot = true;
                });
                btn.onLongPress.AddListener(() =>
                {
                    if (controllingUnit == null)
                    {
                        controllingUnit = UnitManager.Instance.GetUnit(0);
                    }
                    controllingUnit.Transmit(ETransmitType.Attack);
                    controllingUnit.Data.needNextShoot = true;
                });*/
                /*var panel = PveResourceManager.GetResource(PveResourceManager.EPveResType.UI, 26);
                panel.transform.SetParent(canvas.transform);
                panel.GetComponent<RectTransform>().anchoredPosition = new Vector2(-Screen.width / 2 + 300, -Screen.height / 2 + 100);*/
            }
        }

        private GameObject cameraEditor;
        
        public void AddPveCameraEditor()
        {
#if UNITY_EDITOR
            if (cameraEditor == null)
            {
                cameraEditor = PveResourceManager.GetResource(PveResourceManager.EPveResType.UI, 28);
                cameraEditor.SetActive(true);
                cameraEditor.transform.SetParent(canvas.transform);
                cameraEditor.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
            }
#endif
        }
        
        public void StartPve()
        {
            if (joyStick != null)
            {
                joyStick.SetActive(false);
            }
            isRpgControlling = false;
        }

        public void StartRpg()
        {
            if (joyStick != null)
            {
                joyStick.SetActive(true);
            }
            isRpgControlling = true;
        }

        public void ClearStage()
        {
            controllingUnit = null;
            lastDragTarget = null;
        }
        private BattleUnit TouchUnitByTouchPosition(Vector2 pos)
        {
            Ray ray = PveCameraManager.Instance.mainCamera.ScreenPointToRay(new Vector3(pos.x, pos.y, 0f));
            int layer = LayerMask.NameToLayer("PveUnit");
            int hitIndex = -1;
            RaycastHit[] array = Physics.RaycastAll(ray, float.PositiveInfinity, 1 << layer);
            for (int i = 0; i < array.Length; i++)
            {
                RaycastHit raycastHit = array[i];
                BoxCollider boxCollider = raycastHit.collider as BoxCollider;
                if (boxCollider == null)
                {
                    Debug.Log(raycastHit.collider);
                    continue;
                }
                var unitTouch = boxCollider.gameObject.GetComponent<UnitTouch>();
                if (unitTouch != null)
                {
                    var unit = unitTouch.GetUnit();
                    if (unit is BattleUnit battleUnit)
                    {
                        return battleUnit;
                    }
                }
            }
            return null;
        }

        private void OnTouchStart(Vector3 position)
        {
            if (!enable)
            {
                return;
            }
#if UNITY_EDITOR
                touchKnobImage.color = new Color(1,1,1,0.8f);
#endif
            lastTouchUnit = TouchUnitByTouchPosition(position);
        }

        private void OnTouchUp()
        {
#if UNITY_EDITOR
            touchKnobImage.color = new Color(1,1,1,0.3f);
#endif
            lastTouchUnit = null;
            DrawLineTool.GetInstance().DelLine(dragLineId);
            dragLineId = 0;
        }

    
        
        private Vector3 startDragPosition;

        private void OnDragStart(Vector3 position)
        {
            /*if (lastTouchUnit != null && lastTouchUnit.Data.isDraggable)
            {
                lastTouchUnit.Transmit(ETransmitType.OnDrag);
                lastTouchUnit.SetLayer(PveUtils.blackScreenLayer);
                SelectUnit(lastTouchUnit.Data.id);
                PveManager.Instance.StartSkillBulletTime();
                PveManager.Instance.ShowAllHidePoints();
                PveCameraManager.Instance.StartRpgDrag();
            }
            else*/
            //if (Event.current.)
            startDragPosition = position;
            {
                PveCameraManager.Instance.StartDrag();
            }
        }

        private Vector3 targetHidingPoint;

        private void OnDrag(Vector3 position)
        {
            /*targetHidingPoint = Vector3.zero;
            if (state == 0)
            {
                if (lastTouchUnit != null && lastTouchUnit.Data.isDraggable)
                {
                    //var target = TouchUnitByTouchPosition(position);
                    var groundPosition = GetGroundPositionByScreenPosition(position);
                    var hidePoints = PveManager.Instance.GetHidePositions();
                    float autoChooseDistance = 2;
                    Vector3 candidate = Vector3.zero;
                    float distanceFromGroundPosition = float.MaxValue;
                    for (int i = 0; i < hidePoints.Count; i++)
                    {
                        var distance = Vector3.Distance(hidePoints[i], groundPosition);
                        if (distance <= autoChooseDistance)
                        {
                            if (distanceFromGroundPosition > distance)
                            {
                                distanceFromGroundPosition = distance;
                                candidate = hidePoints[i];
                            }
                        }
                    }

                    if (candidate == Vector3.zero)
                    {
                        DoDragToGround(groundPosition);
                        PveManager.Instance.HideHighlightHidePoint();
                    }
                    else
                    {
                        DoDragToHidePoint(candidate);
                        PveManager.Instance.ShowHighlightHidePoint(candidate);
                    }
                    targetHidingPoint = candidate;
                }
                else
                {
                    if (Input.GetKey(KeyCode.LeftControl))
                    {
                        if (touchController.dragVector.y > 0)
                        {
                            PveCameraManager.Instance.RpgCameraAngleUp();
                        }
                        else if (touchController.dragVector.y < 0)
                        {
                            PveCameraManager.Instance.RpgCameraAngleDown();
                        }
                    }
                    //PveCameraManager.Instance.OnDrag(gesture.swipeVector);
                }
            }*/
            
            var vector = position - startDragPosition;
            PveCameraManager.Instance.OnDrag(vector);
           
            startDragPosition = position;
        }
        
        private void OnDragEnd(Vector3 position)
        {
            /*if (state != 0)
            {
                if (PveManager.Instance.isGuiding)
                {
                    SkillDragOutEnd(2);
                    SkillDragEnd(2);
                }
                state = 0;
                return;
            }
            if (lastTouchUnit != null && lastTouchUnit.Data.isDraggable)
            {
                if (targetHidingPoint != Vector3.zero)
                {
                    var arg = ClassManager.Get<AddOrderTransmitArg>();
                    arg.order = ClassManager.Get<UnitOrder>();

                    arg.order.type = UnitOrder.EOrderType.MoveToPosition;
                    arg.order.targetPosition = GetGroundPositionByScreenPosition(position);
                    lastTouchUnit.Data.targetPosition = targetHidingPoint;
                    lastTouchUnit.Data.targetHidingPoint = targetHidingPoint;
                    lastTouchUnit.Data.LeaveHidePoint();
                    lastTouchUnit.Transmit(ETransmitType.AddOrder,arg);
                    ClassManager.Free(arg);
                    PveEffectManager.Instance.PlayEffect((int)ESkillEffect.hidePoint3,targetHidingPoint,Vector3.forward);
                    PveEffectManager.Instance.PlayEffect((int)ESkillEffect.hidePoint2,targetHidingPoint + new Vector3(0,0.1f,0),Vector3.forward,0.6f);
                }
                lastTouchUnit.Transmit(ETransmitType.OnCancelDrag);
                lastTouchUnit.SetLayer(PveUtils.pveUnitLayer);
            }
            PveCameraManager.Instance.EndRpgDrag();
            PveManager.Instance.EndSkillBulletTime();
            PveManager.Instance.HideAllHidePoints();
            PveManager.Instance.HideHighlightHidePoint();*/
            PveCameraManager.Instance.EndDrag();
        }

        private List<Vector2> corners = new List<Vector2>();
        
        public void UpdateMapBoundary(Vector4 boundary)
        {
            corners.Clear();
            mapBoundary = boundary;
            float xmin = mapBoundary.x;
            float xmax = mapBoundary.y;
            float zmin = mapBoundary.z;
            float zmax = mapBoundary.w;
            Vector2 leftTop = new Vector2(xmin,zmax);
            Vector2 leftBottom = new Vector2(xmin,zmin);
            Vector2 rightTop = new Vector2(xmax, zmax);
            Vector2 rightBottom = new Vector2(xmax,zmin);
            corners.Add(leftTop);
            corners.Add(leftBottom);
            corners.Add(rightBottom);
            corners.Add(rightTop);
        }
        
        
        private Vector3 GetGroundPositionByBoundary(Vector3 startPosition,Vector3 targetPosition)
        {
            Vector2 start = new Vector2(startPosition.x,startPosition.z);
            Vector2 target = new Vector2(targetPosition.x,targetPosition.z);

            for (int i = 0; i < corners.Count; i++)
            {
                Vector2 cornerStart = corners[i];
                Vector2 cornerEnd;
                if (i == corners.Count - 1)
                {
                    cornerEnd = corners[0];
                }
                else
                {
                    cornerEnd = corners[i + 1];
                }
                var intersection = PveUtils.GetIntersection(start, target, cornerStart, cornerEnd);
                if (intersection != Vector2.zero)
                {
                    return new Vector3(intersection.x, 0, intersection.y) + (startPosition - targetPosition).normalized * 0.2f;
                }
            }
            return targetPosition;
        }

        private Vector3 GetGroundPositionByScreenPosition(Vector2 pos)
        {
            Ray ray = PveCameraManager.Instance.mainCamera.ScreenPointToRay(new Vector3(pos.x, pos.y, 0f));
                
            var origin = ray.origin;
            var direction = ray.direction;
            var p = origin.y / direction.y;
            return origin - direction * p;
        }
        
        private void DoDragToGround(Vector3 position)
        {
            DrawLineTool.GetInstance().DelLine(dragLineId);
            LineInfo marchLine=new LineInfo()
            {
                color = Color.white,
                speed = 1,
                isPart = true,
                isHeadPart = true,
                startPos = new Vector2(lastTouchUnit.Data.position.x,lastTouchUnit.Data.position.z),
                endPos = new Vector2(position.x,position.z),
            };
            dragLineId = DrawLineTool.GetInstance().AddLine(marchLine);
            if (lastDragTarget != null)
            {
                lastDragTarget.Transmit(ETransmitType.OnPointerUnLock);
            }
            lastDragTarget = null;
        }

        private void DoDragToHidePoint(Vector3 hidePoint)
        {
            DrawLineTool.GetInstance().DelLine(dragLineId);
            LineInfo marchLine=new LineInfo()
            {
                color = Color.yellow,
                speed = 1,
                isPart = true,
                isHeadPart = true,
                startPos = new Vector2(lastTouchUnit.Data.position.x,lastTouchUnit.Data.position.z),
                endPos = new Vector2(hidePoint.x,hidePoint.z),
            };
            dragLineId = DrawLineTool.GetInstance().AddLine(marchLine);
        }

        private void DoDragToTarget(BattleUnit unit)
        {
            if (lastDragTarget != null && unit != lastDragTarget)
            {
                lastDragTarget.Transmit(ETransmitType.OnCancelDrag);
            }

            
            DrawLineTool.GetInstance().DelLine(dragLineId);
            LineInfo marchLine=new LineInfo()
            {
                color = Color.white,
                speed = 1,
                isPart = true,
                isHeadPart = true,
                startPos = new Vector2(lastTouchUnit.Data.position.x,lastTouchUnit.Data.position.z),
                endPos = new Vector2(unit.Data.position.x,unit.Data.position.z),
            };
            dragLineId = DrawLineTool.GetInstance().AddLine(marchLine);
            
            
            if (unit == lastTouchUnit || unit.Data.team != lastTouchUnit.Data.GetTargetTeam(lastTouchUnit.Data.searchType))
            {
                lastDragTarget = null;
                return;
            }
            
            lastDragTarget = unit;
            lastDragTarget.Transmit(ETransmitType.OnPointerLock);
        }

        private void UpdateKnob()
        {
            //canvasTrans.sizeDelta = new Vector2(Screen.width, Screen.height);
            Vector2 uisize = canvasTrans.sizeDelta;//得到画布的尺寸
            Vector2 screenpos = Input.mousePosition;
            Vector2 screenpos2;
            screenpos2.x = screenpos.x - (Screen.width / 2);//转换为以屏幕中心为原点的屏幕坐标
            screenpos2.y = screenpos.y - (Screen.height / 2);
            Vector2 uipos;//UI坐标
            uipos.x = screenpos2.x*  (uisize.x / Screen.width);//转换后的屏幕坐标*画布与屏幕宽高比
            uipos.y = screenpos2.y * ( uisize.y / Screen.height);
            touchKnobTrans.anchoredPosition = uipos;
        }

        public void Pause()
        {
            if(joyStick != null)
                joyStick.SetActive(false);
        }

        public void Resume()
        {
            if(joyStick != null)
                joyStick.SetActive(true);
        }
        
        public void Update()
        {
            cancelHeight = 170;//165f / 750 * Screen.height;
#if UNITY_EDITOR
            UpdateKnob();
            UpdateKeyboard();
#endif
            if (skillUnit != null)
            {
                if (isRpgControlling)
                {
                    if (skillUnit.Data.IsInControl())
                    {
                        StopAction();
                        StopDrag();
                    }
                    else if (this.touchPosition != Vector3.zero)
                    {
                        SkillDrag(0,touchPosition);
                    }
                }
                else
                {
                    StopAction();
                }
            }

            if (joy != null)
            {
                joy.UpdateJoystick();
            }
            //touchController.Update();
        }

        public void OnClickSkill(int index)
        {
            if (state != 0)
            {
                return;
            }
            skillUnit = PveCardManager.Instance.GetCastUnit(index);
            PveCardManager.Instance.ReadyToCast(index);
            lastDragCardIndex = index;
            
            var arg = ClassManager.Get<SkillDirectorShowArg>();
            arg.skillId = PveCardManager.Instance.GetSkillIdByIndex(lastDragCardIndex);
            arg.skillLevel = PveCardManager.Instance.GetSkillLevelByIndex(lastDragCardIndex);
            arg.cardIndex = lastDragCardIndex;

            skillUnit?.Transmit(ETransmitType.SkillReleaseAuto,arg);
            ClassManager.Free(arg);
            
            skillUnit = null;
            this.touchPosition = Vector3.zero;
            PveCardManager.Instance.CancelCast();
            PveManager.Instance.IsAuto = autoStateBeforeTouchSkill;
            lastDragCardIndex = -1;
        }

        private int lastDragCardIndex = -1;

        private YImage activeCancel;
        private YImage inactiveCancel;
        
        private void CheckCancelImage()
        {
            if (activeCancel == null)
            {
                var obj = GameObject.Find("activeCancel");
                if (obj != null)
                {
                    activeCancel = obj.GetComponent<YImage>();
                }
            }

            if (inactiveCancel == null)
            {
                var obj = GameObject.Find("inactiveCancel");
                if (obj != null)
                {
                    inactiveCancel = obj.GetComponent<YImage>();
                }
            }
        }

        private float lastMouseY;
        private float cancelHeight = 170;
        
        private float cardMouseYOffset;

        private void UpdateCancelArea(Vector3 touchPosition)
        {
            var mouseY = touchPosition.y + cardMouseYOffset;
            /*if (mouseY >= cancelHeight && (lastMouseY < cancelHeight || lastMouseY == 0))
            {
                ShowCancelActive();
                HideCancelInActive();
                UseCard();
            }
            else if (mouseY < cancelHeight && (lastMouseY >= cancelHeight || lastMouseY == 0))
            {
                ShowCancelInActive();
                HideCancelActive();
                ShowCard();
            }

            if (mouseY < cancelHeight)
            {
                if (lastFrameMousePosition != Vector3.zero)
                {
                    Vector2 diff = touchPosition - lastFrameMousePosition;
                    //draggingCardTransform.anchoredPosition += diff;
                    //draggingCardTransform.anchoredPosition += new Vector2(0, diff.y);
                }
                lastFrameMousePosition = touchPosition;
            }*/
            lastMouseY = mouseY;
        }
        
        private Dictionary<Transform, Vector3> draggingHideScale = new Dictionary<Transform, Vector3>();
        private Animator draggingCardAnimator;
        

        private bool autoStateBeforeTouchSkill;
        
        public void SkillTouchStart(int index, GameObject card)
        {
            state = 0;

            if (!PveManager.Instance.IsStageActive || TimeManager.gameTimeScale == 0)
            {
                return;
            }
            
            autoStateBeforeTouchSkill = PveManager.Instance.IsAuto;
            PveManager.Instance.IsAuto = false;
            
        }

        public void SkillDrag(int index,Vector3 touchPosition)
        {
            if (skillUnit != null)
            {
                //this.touchPosition = touchPosition;
                float leftLimit = 100f / 1334 * Screen.width;
                var arg = ClassManager.Get<SkillDirectorMoveArg>();
                touchPosition.x = Mathf.Max(0 + leftLimit,touchPosition.x);
                touchPosition.x = Mathf.Min(Screen.width, touchPosition.x);
                touchPosition.y = Mathf.Max(0,touchPosition.y);
                touchPosition.y = Mathf.Min(Screen.height, touchPosition.y);
                arg.position = GetGroundPositionByScreenPosition(touchPosition);//GetGroundPositionByBoundary(skillUnit.Data.position,GetGroundPositionByScreenPosition(Input.mousePosition));
                skillUnit.Transmit(ETransmitType.SkillDirectorMove,arg);
                ClassManager.Free(arg);
            }
            UpdateCancelArea(touchPosition);
        }

        public void SkillTouchEnd(int index, GameObject card)
        {
            if (state == 0)
            {
                state = 3;
                SkillDragEnd(index);
            }
        }

        public void SkillDragStart(int index,Vector3 touchPosition)
        {
            state = 1;
            skillUnit = PveCardManager.Instance.GetCastUnit(index);
            PveCardManager.Instance.ReadyToCast(index);
            lastDragCardIndex = index;
            if (skillUnit != null)
            {
                if (skillUnit.Data.CanUseSkill())
                {
                    var arg = ClassManager.Get<SkillDirectorShowArg>();
                    arg.skillId = PveCardManager.Instance.GetSkillIdByIndex(lastDragCardIndex);
                    arg.skillLevel = PveCardManager.Instance.GetSkillLevelByIndex(lastDragCardIndex);
                    arg.cardIndex = lastDragCardIndex;
                    var heroId = PveCardManager.Instance.GetHeroIdByIndex(lastDragCardIndex);
                    skillUnit.Transmit(ETransmitType.ShowDirector,arg);
                    ResidentHandler.Inst.GetFunction("pveManager.UpdateHeroCastingSkill").Call(index,heroId,arg.skillId,arg.skillLevel,true);
                }
            }
        }
        
        public void StopAction()
        {
            //Debug.LogError("StopAction");
            // lastMouseY = 0;
            // SkillDragOutEnd(0);
            // SkillDragEnd(0);
            if (state != 0)
            {
                state = 0;
            }

            PveManager.Instance.IsAuto = autoStateBeforeTouchSkill;
        }
        
        public void SkillDragEnd(int index)//再end
        {
            lastMouseY = 0;
            bool isSuccess = false;
            if (state == 1)//说明取消了
            {
                isSuccess = false;
            }
            else if (state == 3)//说明释放成功了
            {
                isSuccess = true;
            }

            int skillId = PveCardManager.Instance.GetSkillIdByIndex(lastDragCardIndex);
            int heroId = PveCardManager.Instance.GetSkillLevelByIndex(lastDragCardIndex);
            int skillLevel = PveCardManager.Instance.GetSkillLevelByIndex(lastDragCardIndex);
            ResidentHandler.Inst.GetFunction("pveManager.UpdateHeroCastingSkill").Call(index,heroId,skillId,skillLevel,false);
            var darg = ClassManager.Get<HideDirectorArg>();
            darg.isUseSkillSuccess = isSuccess;
            skillUnit?.Transmit(ETransmitType.HideDirector,darg);
            ClassManager.Free(darg);

            if ( isSuccess)
            {
                var arg = ClassManager.Get<SkillReleaseArg>();
                arg.cardIndex = lastDragCardIndex;
                skillUnit?.Transmit(ETransmitType.SkillRelease,arg);
                ClassManager.Free(arg);
            }
            
            skillUnit = null;
            this.touchPosition = Vector3.zero;
            PveCardManager.Instance.CancelCast();
            PveManager.Instance.IsAuto = autoStateBeforeTouchSkill;
            lastDragCardIndex = -1;
        }

        public void BeforeReleaseCard(int index)
        {
            // var pos = draggingCardTransform.anchoredPosition;
            // draggingCardDisappearAnchoredPosition = pos;
            //draggingCardTransform.DOAnchorPosY(pos.y + 100, 0.2f);
            //draggingCardAnimation.Stop();
            /*if (draggingCardAnimator != null)
            {
                draggingCardAnimator.SetTrigger("ani_pvecard_release");
            }*/
            ResidentHandler.Inst.GetFunction("pveManager.DoSkillRelease").Action(index);
        }

        public void StopDrag()
        {
            lastMouseY = 0;
            ResidentHandler.Inst.GetFunction("pveManager.RpgCardHideCancel").Call();

            if (lastDragCardIndex < 0)
            {
                return;
            }
            
            int skillId = PveCardManager.Instance.GetSkillIdByIndex(lastDragCardIndex);
            int heroId = PveCardManager.Instance.GetSkillLevelByIndex(lastDragCardIndex);
            int skillLevel = PveCardManager.Instance.GetSkillLevelByIndex(lastDragCardIndex);
            ResidentHandler.Inst.GetFunction("pveManager.UpdateHeroCastingSkill").Action(lastDragCardIndex,heroId,skillId,skillLevel,false);
            
            var arg = ClassManager.Get<HideDirectorArg>();
            arg.isUseSkillSuccess = false;
            skillUnit?.Transmit(ETransmitType.HideDirector,arg);
            ClassManager.Free(arg);
            skillUnit = null;
            this.touchPosition = Vector3.zero;
            PveCardManager.Instance.CancelCast();
        }

        public void SkillDragOutEnd(int id)//先outEnd
        {
            state = 3;
            //skillUnit?.Transmit(ETransmitType.SkillRelease);
        }

        private void SelectUnit(int id,bool callUI = true)
        {
            currentSelectUnit?.Transmit(ETransmitType.OnUnSelected);
            var unit = PveManager.Instance.GetUnit(id);
            if (unit != null)
            {
                unit.Transmit(ETransmitType.OnSelected);
                currentSelectUnit = unit;
                if (callUI)
                {
                    ResidentHandler.Inst.GetFunction("pveManager.SelectHero").Action(unit.Data.id);
                }
            }
        }

        public void UnitDead(BattleUnit unit)
        {
            if (unit ==  skillUnit)
            {
                StopAction();
                StopDrag();
                /*unit.Transmit(ETransmitType.OnUnSelected);
                var list = UnitManager.Instance.GetAllUnitByTeam(0);
                for (int i = 0; i < list.Count; i++)
                {
                    if (!list[i].Data.isDead)
                    {
                        SelectUnit(list[i].Data.id);
                        break;
                    }
                }*/
            }
        }

        
        public void OnClickHero(int id)
        {
            SelectUnit(id,false);
        }
        
        public void PlaceObstacle(Vector3 mousePosition)
        {
            //var pos = GetGroundPositionByScreenPosition(mousePosition);
            //PveManager.Instance.AddObstacle(pos);
        }

        private BattleUnit controllingUnit;

        private void UpdateKeyboard()
        {
            if (PveManager.Instance.isManualMoving)
            {
                float h = 0;
                float v = 0;
                if (Input.GetKey(KeyCode.A))
                {
                    h -= 1;
                }

                if (Input.GetKey(KeyCode.D))
                {
                    h += 1;
                }

                if (Input.GetKey(KeyCode.W))
                {
                    v += 1;
                }

                if (Input.GetKey(KeyCode.S))
                {
                    v -= 1;
                }

                if (h != 0 || v != 0)
                {
                    UnitMove(new Vector2(h,v).normalized,9999);
                }
            }
        }

        private void UnitAim(Vector2 orientation)
        {
            if (controllingUnit == null)
            {
                controllingUnit = UnitManager.Instance.GetUnit(0);
            }
            if (controllingUnit == null)
            {
                return;
            }
            var origonForward = new Vector3(orientation.x,0,orientation.y);
            var angle = PveCameraManager.Instance.cameraTrans.localEulerAngles.y;
            var realForward = Quaternion.AngleAxis(angle, Vector3.up) * origonForward;
            if (realForward != controllingUnit.Data.manualAimForward)
            {
                controllingUnit.Data.manualAimForward = realForward;
                controllingUnit.Transmit(ETransmitType.AimSearch);
            }
        }

        private void UnitAttack()
        {
            controllingUnit.Transmit(ETransmitType.Attack);
            controllingUnit.Data.needNextShoot = true;
        }
        
        private void UnitMove(Vector2 orientation,float distance)
        {
            if (controllingUnit == null)
            {
                controllingUnit = UnitManager.Instance.GetUnit(0);
            }

            if (controllingUnit == null || !controllingUnit.Data.isManualMoving)
            {
                return;
            }

            var origonForward = new Vector3(orientation.x,0,orientation.y);
            var angle = PveCameraManager.Instance.cameraTrans.localEulerAngles.y;
            var realForward = Quaternion.AngleAxis(angle, Vector3.up) * origonForward;
            if (distance > 1 && !controllingUnit.Data.isMoveAttacking && !controllingUnit.Data.IsInSkill() && !controllingUnit.Data.isReloading && !controllingUnit.Data.IsAttackInRange())//3000
            {
                controllingUnit.Data.moveState = 2;
            }
            else if (distance > 1)
            {
                controllingUnit.Data.moveState = 1;
            }
            else if (!controllingUnit.Data.IsInSkill())
            {
                controllingUnit.Data.moveState = 0;
            }
            if (realForward != controllingUnit.Data.manualForward && !controllingUnit.Data.IsInSkill())
            {
                controllingUnit.Data.manualForward = realForward;
                controllingUnit.Transmit(ETransmitType.ManualMove);
            }
        }

        public void Dispose()
        {
            controllingUnit = null;
            GameObject.Destroy(canvas);
            instance = null;
            
            var handler = ResidentHandler.Inst;
            if(handler == null) return;
            handler.RemoveFunction("pveManager.UpdateHeroCastingSkill");
            handler.RemoveFunction("pveManager.DoSkillRelease");
            handler.RemoveFunction("pveManager.RpgCardHideCancel");
            handler.RemoveFunction("pveManager.UpdateHeroCastingSkill");
            handler.RemoveFunction("pveManager.SelectHero");
        }
    }
}
